package com.boxin.ims.modules.wechat.web.front;

import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import sun.misc.BASE64Encoder;

import com.boxin.framework.base.dao.DaoHelper;
import com.boxin.framework.base.dao.OpResult;
import com.boxin.framework.base.utils.Constants;
import com.boxin.ims.modules.momarketing.common.QRCodeUtils;
import com.boxin.ims.modules.momarketing.entity.CouponConfig;
import com.boxin.ims.modules.momarketing.entity.QRCode;
import com.boxin.ims.modules.momarketing.entity.Terminal;
import com.boxin.ims.modules.momarketing.service.CouponConfigService;
import com.boxin.ims.modules.momarketing.service.QRCodeService;
import com.boxin.ims.modules.momarketing.service.TerminalService;
import com.boxin.ims.modules.recharge.entity.Recharge;
import com.boxin.ims.modules.recharge.entity.RechargeCache;
import com.boxin.ims.modules.recharge.entity.RechargeLog;
import com.boxin.ims.modules.recharge.service.RechargeCacheService;
import com.boxin.ims.modules.recharge.service.RechargeLogService;
import com.boxin.ims.modules.recharge.service.RechargeService;
import com.boxin.ims.modules.sys.utils.EncryptUtils;
import com.boxin.ims.modules.wechat.entity.UserDefine;
import com.boxin.ims.modules.wechat.entity.WechatMember;
import com.boxin.ims.modules.wechat.service.LotteryRecordService;
import com.boxin.ims.modules.wechat.service.SeckillGainerService;
import com.boxin.ims.modules.wechat.service.WechatDaoHelper;
import com.boxin.ims.modules.wechat.service.WechatMemberService;
import com.boxin.ims.modules.wechat.utils.ScoreUtils;
import com.boxin.ims.modules.wechat.utils.WechatUtils;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.BaseEntity;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;


/**
 * @author Jakemanse
 * @date 2013-10-3
 * @function <p> 核销专用控制器 </p>
 */
@Controller
@RequestMapping(value = Global.FRONT_PATH+"/wechat/verification")
public class VerificationFrontController extends BaseController{
	
	private final Logger logger = Logger.getLogger(VerificationFrontController.class);
	
	@Autowired
	private LotteryRecordService lotteryRecordService;
	
	@Autowired
	private SeckillGainerService seckillGainerService;
	
	@Autowired
	private CouponConfigService couponConfigService;
	
	@Autowired
	private WechatMemberService wechatMemberService;
	
	@Autowired
	private RechargeService rechargeService;
	
	@Autowired
	private RechargeLogService rechargeLogService;
	
	
	@Autowired
	private WechatDaoHelper wechatDaoHelper;
	
	
	@Autowired
	private RechargeCacheService rechargeCacheService;
	
	@Autowired
	private QRCodeService qrCodeService;
	
	
	
	@Autowired
	SystemService systemService;
	
	@Autowired
	TerminalService terminalService;
	
	@Autowired
	private DaoHelper daoHelper;
	
	private HttpServletRequest request;
	private HttpServletResponse response;
	
	
	private String sn;
	private String time;
	private String verify1;
	private String verify2;
	private String clientId;
	private String clientType;
	private String clientName;
	private Terminal terminal = null;
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-3  上午11:54:02
	 * @function <p> 核销入口 </p>
	 * @param request 
	 * @param response
	 * @param model
	 * <p>
	 * 		参数说明：
	 * 		sn:二维码内容，即中奖序列号
	 * 		key:md5密钥，服务端设置
	 * 		key2:md5密钥2  服务器设置
	 * 		time:时间 
	 * 		verify1:密文1   由  time+key 的MD5生成
	 * 		varify2:密文2 由     sn+key   的MD5生成
	 *      clientId:  端的ID
	 * </p>
	 * @return
	 */
	@RequestMapping(value="verify")
	public String verify( HttpServletRequest request, HttpServletResponse response, Model model) {
		
		this.request = request;
		this.response = response;
			
		sn = request.getParameter("sn");		//二维码序列号
		time = request.getParameter("time");	//时间 
		verify1 = request.getParameter("v1");	//加密1
		verify2 = request.getParameter("v2");	//加密2 
		clientId = request.getParameter("clientId");	//终端号
		clientType=	request.getParameter("clientType");	//终端类型
		clientName=	request.getParameter("clientName");	//终端登录名
		  
		logger.debug("核销请求数据:\nsn="+sn+"\r\ntime="+time+"\r\nv1="+verify1+"\r\nv2="+verify2+"\r\nclientId="+clientId+"\r\nclientType="+clientType);
		/**
		 * 检查请求参数是否为空
		 */
		if(sn== null || time==null || verify1==null || verify2==null || clientId==null || clientType==null){
			writeToUser(request, response, false, "您提交的数据不完整,请联系管理员", "");
			return null;
		}
		
		
		/**
		 * 如果不是比特堡
		 */
		if("bitebao".equals(clientId)){
			clientId = "1";
		}
		
		//验证客户端
		this.terminal = terminalService.get(Long.parseLong(clientId));
		if(this.terminal == null){
			writeToUser(request, response, false, "该终端不存在,请先设置好设置配置再行核销", "");
			return null;
		}else{
			if(!BaseEntity.STATUS_NORMAL.equals(terminal.getStatus())){
				writeToUser(request, response, false, "该终端已被锁定,请解除锁定后再使用!", "");
				return null;
			}
		}	
		
		
		String key=Constants.MD5ENCODER_VERIFY_KEY;
		
		String vstr1 =   getMD5EncodeString((time.trim()+key)).replaceAll(" ", "");
		logger.debug("java v1:"+vstr1);
		//验证1
		if(!vstr1.equals(verify1.replaceAll(" ", "+"))){
			writeToUser(request, response, false, "您提交的数据是非法端核销数据请求,请不要尝试破坏和攻击本系统,否则您将受到相关法律的裁,谢谢合作!", "");
			return null;
		} 
		
		//验证2
		String vsn = sn.replaceAll("-", "");
        vsn = vsn.substring(0, 15);
		String vstr2 = getMD5EncodeString((vsn.trim()+key)).replaceAll(" ", "");
		logger.debug("java v2:"+vstr2);
		if(!vstr2.equals(verify2.replaceAll(" ", "+"))){
			writeToUser(request, response, false, "您提交的数据是非法端核销数据请求,请不要尝试破坏和攻击本系统,否则您将受到相关法律的裁,谢谢合作!", "");
			return null;
		} 
			
		
		//验证商店
		
		//验证客户端
		
		
		//通过sn码解析出商家id
		String uid=sn.substring(3,sn.indexOf("-"));
		
		//验证客户端的user
		if(terminal.getUser()==null|| terminal.getUser().getId()==null){
			writeToUser(request, response, false, "您提交的数据是非法端核销数据请求,请不要尝试破坏和攻击本系统,否则您将受到相关法律的裁,谢谢合作!", "");
			return null;
		}
		//验证sn码中的商家id和客户端的商家id
		System.out.println("uid="+uid+";terminal_uid="+terminal.getUser().getId().toString());
		if(!(uid.trim()).equals(terminal.getUser().getId().toString())){
			writeToUser(request, response, false, "本店无效二维码,该码非本店二维码电子凭证,请到该码发放者指定的单位去核销，谢谢！", "");
			return null;
		}
		
		//验证序列号
		if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_CIRCLE_SHARE)){//微圈转发中奖券
			verifyCircleShare();
		}else if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_COUPON)){//优惠券
			veryfyCoupon();
		}else if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_EXCHANGE)){//积分兑换
			verifyExchange();
		}else if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_LOTTERY)){	//抽奖
			verifyLottery();
		}else if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_SECKILL)){	//秒杀中奖
			verifySeckill();
		}else if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_TICKET)){	//入场券
			//queryTicketBySN
			verifyTicketBySN();
			//verifyTicketBySN
		}else if(sn.startsWith(QRCodeUtils.QRCODE_VTYPE_PAY_MONEY)){
			verifyPayMoneyBySN();
		} 
		
		
		return  null;
	}
	
	
	/**
	 * 储值消费
	 *@author xiaoqian
	 * 2014-7-10下午5:27:13
	 */
	private void verifyPayMoney(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject( "com.boxin.ims.wechat.queryCircleShareBySN", sn);
		
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		
		
		//开始核销
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		
		updateVerifyToDB(remarks, "verifyCircleShareBySN");
		resultMap.put("lotteryType", "微圈分享");
		resultMap.put("name", resultMap.get("award_name"));
		writeSuccessToUser(request, response, true, "", "微圈转发凭证核销成功,谢谢!",resultMap);
		
	}
	
	
	
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:56:31
	 * @function <p> 核销微圈转发得奖凭证 </p>
	 */
	private void verifyCircleShare(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject( "com.boxin.ims.wechat.queryCircleShareBySN", sn);
		
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		
		//判断时间
		if(!checkDateTime(resultMap)) return ;	//时间过期
		
		
		//开始核销
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		
		updateVerifyToDB(remarks, "verifyCircleShareBySN");
		resultMap.put("lotteryType", "微圈分享");
		resultMap.put("name", resultMap.get("award_name"));
		writeSuccessToUser(request, response, true, "", "微圈转发凭证核销成功,谢谢!",resultMap);
		
	}
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:56:56
	 * @function <p>核销优惠券凭证  </p>
	 */
	private void veryfyCoupon(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject("com.boxin.ims.wechat.queryCouponBySN", sn);
		
		//检查是否有该条讯录
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		
		//判断时间
		if(!checkDateTime(resultMap)) return ;	//时间过期		
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		//开始核销
		updateVerifyToDB(remarks, "verifyCouponBySN");
		
		WechatMember wechatMember = wechatMemberService.get(Long.parseLong(resultMap.get("member_id").toString()));
		
		CouponConfig config =	couponConfigService.get(Long.parseLong(resultMap.get("config_id").toString())) ;
		
		String mStr ="";
		if(wechatMember != null && StringUtils.isNotEmpty(wechatMember.getName())){
			mStr = "("+wechatMember.getName()+")";
			
			resultMap.put("name", mStr+resultMap.get("name"));
		}
		
		resultMap.put("lotteryType", "优惠券");
		
		writeSuccessToUser(request, response, true, "", mStr+"优惠券凭证核销成功,谢谢!",resultMap);
	}
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:57:16
	 * @function <p> 核销秒杀凭证 </p>
	 */
	private void verifySeckill(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject("com.boxin.ims.wechat.querySeckillGainerBySN", sn);
		
		//检查是否有该条讯录
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
				
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		//判断时间
		if(!checkDateTime(resultMap)) return ;	//时间过期			
		
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		updateVerifyToDB(remarks, "verifySeckillBySN");
		resultMap.put("lotteryType", "秒杀");
		writeSuccessToUser(request, response, true, "", "秒杀奖品凭证核销成功,谢谢!",resultMap);
		
	}
	
	/**
	 * @author Jakemanse
	 * @time 2014-2-5  下午2:05:17
	 * @function <p> 核销入场券 </p>
	 */
	private void verifyTicketBySN(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject("com.boxin.ims.wechat.queryTicketBySN", sn);
		
		//检查是否有该条讯录
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		//判断时间
		if(!checkDateTime(resultMap)) return ;	//时间过期			
		
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		updateVerifyToDB(remarks, "verifyTicketBySN");
		resultMap.put("lotteryType", "电子券");
		writeSuccessToUser(request, response, true, "", resultMap.get("name")+"核销成功,谢谢!",resultMap);
		
	}
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2014-7-10  下午5:18:22
	 * @function <p> 支付凭证核销 </p>
	 */
	private void verifyPayMoneyBySN(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject("com.boxin.ims.wechat.verifyPayMoneyBySN", sn);
		
		//检查是否有该条讯录
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		//判断时间永过期
		///if(!checkDateTime(resultMap)) return ;	//时间过期			
		
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		updateVerifyToDB(remarks, "verifyPayMoneyBySN");
		resultMap.put("lotteryType", "在线支付");
		writeSuccessToUser(request, response, true, "", resultMap.get("name")+"核销成功,谢谢!",resultMap);
		
	}
	
	
	
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:57:33
	 * @function <p> 核销中奖凭证 </p>
	 */
	private void verifyLottery(){
		
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject("com.boxin.ims.wechat.queryLotteryRecordBySN", sn);
		//检查是否有该条讯录
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		//判断时间
		if(!checkDateTime(resultMap)) return ;	//时间过期	
				
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType+",核销人:"+terminal.getName()+",核销单位:"+terminal.getRemarks();
		
		updateVerifyToDB(remarks, "verifyLotteryRecordSN");
		resultMap.put("lotteryType", "抽奖");
		writeSuccessToUser(request, response, true, "", "抽奖凭证核销成功,谢谢!",resultMap);
	}
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:57:47
	 * @function <p> 核销积分兑换凭证 </p>
	 */
	private void verifyExchange(){
		Map<String,Object> resultMap = (Map<String,Object> )daoHelper.queryForObject("com.boxin.ims.wechat.queryExchangeRecordBySN", sn);
		
		//检查是否有该条讯录
		if(!checkQueryResult(resultMap))	return;			//检查是否该条讯录
		//判断状态，
		if(!checkStatus(resultMap.get("status"))) return;		//拳术不正确
		//判断时间
		if(!checkDateTime(resultMap)) return ;	//时间过期	
		
		String remarks = (resultMap.get("remarks")==null)?"":resultMap.get("remarks").toString();
		remarks += "核销生成功,核销设备ID:"+clientId+",设备类型:"+clientType;
		updateVerifyToDB(remarks, "verifyExchangeRecordSN");
		resultMap.put("lotteryType", "积分兑换");
		writeSuccessToUser(request, response, true, "", "核销成功,谢谢!",resultMap);
		
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:58:12
	 * @function <p>更新数据库  </p>
	 * @param remarks
	 * @param sqlName
	 */
	private void updateVerifyToDB(String remarks,String sqlName){
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("sn", sn);
		params.put("terminalId", terminal.getId());
		params.put("terminalName", terminal.getName());
		params.put("terminalRemarks", terminal.getRemarks());
		
		params.put("remarks", remarks);
		OpResult opResult = daoHelper.update("com.boxin.ims.wechat."+sqlName,params);
		
		//TODO 处理的激活冻结的  充值资金
		Runnable runner = new Runnable() {
			@Override
			public void run() {
				logger.debug("查找二维码对象:"+sn);
				QRCode qrcode = qrCodeService.getBySN(sn);
				if(qrcode!=null){
					WechatMember member = qrcode.getMember();
					if(member!= null){
						Long memberId = qrcode.getMember().getId();
						WechatMember childMember = wechatMemberService.get(memberId);
						RechargeCache rechargeCache = new RechargeCache();
						rechargeCache.setStatus(RechargeCache.NOT_ACTIVATE);
						rechargeCache.setChildMember(childMember);
						
						List<RechargeCache> cacheList = 	rechargeCacheService.find(rechargeCache);
						if(cacheList!=null && !cacheList.isEmpty()){
							logger.debug("查找 ChildMember 为"+childMember.getName()+"["+childMember.getId()+"]的父推荐人冻结项。");
							for(RechargeCache cache:cacheList){
								WechatMember parentMember =	cache.getParentMember();
								
								int money = cache.getMoney();
								int leftMoney = parentMember.getMoney();
								int tmoney = money + leftMoney;
								
								parentMember.setMoney(tmoney);
								wechatMemberService.save(parentMember);			//更新余额
								//会员卡及 会员充值记录
								//查找会员
								Recharge recharge = rechargeService.getRechargeByMemberId(parentMember.getId());
								//存在则更新
								if(recharge != null){
									recharge.setMoney(tmoney);
									recharge.setName(parentMember.getName());
									rechargeService.save(recharge);
									
								}else{
									//不存在则添加
									recharge = new Recharge();
									recharge.setMember(parentMember);
									recharge.setName(parentMember.getName());
									recharge.setUser(terminal.getUser());
									recharge.setMoney(tmoney);
									recharge.setType(Recharge.CARD_TYPE_GENERAL);
									recharge.setNumber(parentMember.getNumber());
									rechargeService.save(recharge);
									
									parentMember.setMoney(tmoney);
									wechatMemberService.save(parentMember);
								}
								
								//添加充值日志  流水
								RechargeLog  rechargeLog = new RechargeLog();
								rechargeLog.setMember(parentMember);
								rechargeLog.setUser(terminal.getUser());
								rechargeLog.setName(parentMember.getName());
								rechargeLog.setMoney(money);
								rechargeLog.setType(RechargeLog.TYPE_RECHARGE);	//
								rechargeLog.setRecharge(recharge);
								rechargeLog.setRemarks("推荐会员"+childMember.getName()+"奖励"+money/100+"元.");
								String serialNo = wechatDaoHelper.generateRechargeSerialNumber(terminal.getUser().getId());
								rechargeLog.setNumber(parentMember.getNumber());
								rechargeLog.setSerialNo(serialNo);
								rechargeLogService.save(rechargeLog);
								
								
								//更新 RechargeCache 
								
								cache.setStatus(RechargeCache.ACTIVATE);
								cache.setUpdateTime(new Date());
								cache.setRemarks("推荐成功获得奖金 "+cache.getMoney()/100+"元.");
								rechargeCacheService.save(cache);
								
								
							}
						}else{
							logger.debug("未查找 到ChildMember 为"+childMember.getName()+"["+childMember.getId()+"]的父推荐人的冻结项。");
						}
					}
				}
				
			}
		};
		
		new Thread(runner).start();		//启动线程
		
		
		
		
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午4:02:05
	 * @function <p> 判断是否过期 </p>
	 * @param endTime
	 * @return
	 */
	private boolean isOutOfDate(Date endTime){
		java.util.Calendar c1=java.util.Calendar.getInstance();	//当前时间
		java.util.Calendar c2=java.util.Calendar.getInstance();
		try {
			c1.setTime(new Date());
			c2.setTime(endTime);
		} catch (Exception e) {
			System.err.println("格式不正确");
			return true;
		}
		int result = c1.compareTo(c2);
		if (result > 0){	//c1>c2  过期
			return true;
		} 
		return false;
	}
	
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:15:43
	 * @function <p> 根据凭证号得到凭证类型 </p>
	 * @param sn
	 * @return
	 */
	private String getQRCodeType(String sn){
		String regex = "^("+QRCodeUtils.QRCODE_VTYPE_CIRCLE_SHARE+"|"+QRCodeUtils.QRCODE_VTYPE_COUPON+"|"+QRCodeUtils.QRCODE_VTYPE_EXCHANGE+"|"+QRCodeUtils.QRCODE_VTYPE_LOTTERY+"|"+QRCodeUtils.QRCODE_VTYPE_SECKILL+")(\\d+)-(.*)$";
		Pattern p = Pattern.compile(regex);
		 Matcher matcher = p.matcher(sn);
		 if( matcher.matches()){
			 int count = matcher.groupCount();
			 if(count==3){
				 
				 String s1 = matcher.group(1);
				 String s2 = matcher.group(2);
				 String s3 = matcher.group(3);
				 return s1;
			 }
		 }
		 
		return null;
	}
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-6  下午11:52:59
	 * @function <p> 检查查询到的记录 </p>
	 * @param resultMap
	 * @return
	 */
	private boolean checkQueryResult(Map<String,Object> resultMap){
		if(resultMap !=null && !resultMap.isEmpty()){
			return true;
		}else{
			writeToUser(request, response, false, "核销失败,未找该电子凭证信息数据!", "核销失败,谢谢!");
			return false;
		}
	}
	
	private boolean checkStatus(Object oStatus){
		if(oStatus == null) {
			writeToUser(request, response, false, "该凭证的状态发生异常,请确认其有效性.", "核销失败");
			return false;
		}
		
		
		String status = oStatus.toString();
		if(!BaseEntity.STATUS_NORMAL.equals(status)){
			//失败
			String reply="";
			if(BaseEntity.STATUS_DROP.equals(status)){
				reply = "此凭证已作废.";
				
			}
			if(BaseEntity.STATUS_CLEAR.equals(status)){
				reply = "此凭证已核销使用过，不可再重复使用.";
			}
			
			writeToUser(request, response, false, reply, "核销失败");
			return false;
		}
		return true;
	}
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午4:28:33
	 * @function <p> 检查时间合法性，过期直接反馈给用户 </p>
	 * @param endTime
	 */
	private boolean checkDateTime( Map<String,Object> resultMap){
		//判断时间
		if(isOutOfDate((Date)resultMap.get("end_time"))){
			//过期
			String reply = "此凭证已过期,有效时期为:"+resultMap.get("create_time")+resultMap.get("end_time");
			writeToUser(request, response, false, reply, "核销失败");
			return false;
		}	
		
		return true;
	}
	
	
	private boolean checkClient(String clientId){
		return true;
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午3:15:00
	 * @function <p> 根据序列表号 得到UserId </p>
	 * @param sn
	 * @return
	 */
	private String getUserIdBySerialNumber(String sn){
		String regex = "^("+QRCodeUtils.QRCODE_VTYPE_CIRCLE_SHARE+"|"+QRCodeUtils.QRCODE_VTYPE_COUPON+"|"+QRCodeUtils.QRCODE_VTYPE_EXCHANGE+"|"+QRCodeUtils.QRCODE_VTYPE_LOTTERY+"|"+QRCodeUtils.QRCODE_VTYPE_SECKILL+")(\\d+)-(.*)$";
		Pattern p = Pattern.compile(regex);
		 Matcher matcher = p.matcher(sn);
		 if( matcher.matches()){
			 int count = matcher.groupCount();
			 if(count==3){
				 
				 String s1 = matcher.group(1);
				 String s2 = matcher.group(2);
				 String s3 = matcher.group(3);
				 return s2;
			 }
		 }
		return null;
	}
	
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午4:16:23
	 * @function <p> 返回结果给用户 </p>
	 * @param request
	 * @param response
	 * @param success
	 * @param errorInfo
	 * @param tip
	 */
	public void writeToUser(HttpServletRequest request, HttpServletResponse response,boolean  success,String errorInfo,String tip){
		String xml = wrapXML(success, errorInfo, tip,null);
		responseXML(request, response, xml);
	}
	
	public void writeSuccessToUser(HttpServletRequest request, HttpServletResponse response,boolean  success,String errorInfo,String tip,Map<String,Object> resultMap ){
		String xml = wrapXML(success, errorInfo, tip,resultMap);
		responseXML(request, response, xml);
	}
	
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-4  下午4:13:22
	 * @function <p> 包装XML  </p>
	 * @param success
	 * @param errorInfo
	 * @param tip
	 * @return
	 */
	private String wrapXML(boolean success,String errorInfo,String tip,Map<String,Object> resultMap ){
		
		StringBuffer xml = new StringBuffer();
		xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
		xml.append("<response>");
		xml.append("<success>").append(success).append("</success>");
		
		if(resultMap!=null){
			
			if(resultMap.get("name") != null){
				xml.append("<lotteryName>").append(resultMap.get("name")).append("</lotteryName>");			//奖品名称
			}
			
			if(resultMap.get("userName") != null){
				xml.append("<userName>").append(resultMap.get("userName")).append("</userName>");			//奖品名称
			}
			
			if(resultMap.get("createTime") != null){
				xml.append("<createTime>").append(resultMap.get("createTime")).append("</createTime>");			//创建时间
			}
			
			if(resultMap.get("endTime") != null){
				xml.append("<endTime>").append(resultMap.get("endTime")).append("</endTime>");			//过期时间
			}
			
			if(resultMap.get("lotteryType") != null){
				xml.append("<lotteryType>").append(resultMap.get("lotteryType")).append("</lotteryType>");			//奖品名称
			}
			
			
			if(resultMap.get("userId") != null){
				xml.append("<userId>").append(resultMap.get("userId")).append("</userId>");			//奖品名称
			}
			
			if(resultMap.get("terminalId") != null){
				xml.append("<terminalId>").append(resultMap.get("terminalId")).append("</terminalId>");			//奖品名称
			}
			
			
		}
		
		
		xml.append("<errorInfo>").append(errorInfo).append("</errorInfo>");
		xml.append("<tip>").append(tip).append("</tip>");
		xml.append("</response>");
		logger.debug(xml.toString());
		return xml.toString();
		
	}
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-21  上午11:06:47
	 * @function <p>用户帐号登录  </p>
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value="login")
	public void wsLogin(HttpServletRequest request, HttpServletResponse response, Model model){
		String name = request.getParameter("name");
		String pwd  = request.getParameter("password");
		User user = UserUtils.getUserByUsername(name);
		if(user == null){
			writeToUser(request, response, false, "您输入的用户名不存在.", "您输入的用户名不存在.");
		}
		boolean login =	systemService.validatePassword(pwd, user.getPassword());
		if(login){
			Map<String,Object> resultMap = new HashMap<String,Object>();
			resultMap.put("userId", user.getId()+"");
			writeSuccessToUser(request, response, login, "", "登录成功",resultMap);
		}else{
			writeToUser(request, response, login, "用户名或密码错误，登录失败！", "用户名或密码错误，登录失败！");
			
		}
		
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2013-10-21  上午11:07:30
	 * @function <p> 终端登录  </p>
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value="tmlogin")
	public void terminalLogin(HttpServletRequest request, HttpServletResponse response, Model model){
		String name = request.getParameter("name");
		String number =  request.getParameter("number");
		String pwd  = request.getParameter("password");
	//	terminalService.get(id);
		Terminal terminal =	terminalService.getTerminalByNameAndPassword(name, systemService.entryptMD5Pssword(pwd));
		if(terminal == null){
			writeToUser(request, response, false, "您输入的终端用户名不存在.", "您输入的终端用户名不存在.");
			return ;
		}
		boolean login =	terminal.getPassword().equals(systemService.entryptMD5Pssword(pwd));
		if(login){
			User user = terminal.getUser();
			Map<String,Object> resultMap = new HashMap<String,Object>();
			resultMap.put("userId", user.getId()+"");
			resultMap.put("terminalId", terminal.getId()+"");
			writeSuccessToUser(request, response, login, "", "登录成功",resultMap);
		}else{
			writeToUser(request, response, login, "用户名或密码错误，登录失败！", "用户名或密码错误，登录失败！");
			
		}
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2014-3-5  上午11:35:31
	 * @function <p> 验证请求参数的合法性  </p>
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	private boolean verifyParameters(HttpServletRequest request, HttpServletResponse response, Model model){
		//认证
		sn = request.getParameter("sn");		//二维码序列号
		time = request.getParameter("time");	//时间 
		verify1 = request.getParameter("v1");	//加密1
		verify2 = request.getParameter("v2");	//加密2 
		clientId = request.getParameter("clientId");	//终端号
		clientType=	request.getParameter("clientType");	//终端类型
		clientName=	request.getParameter("clientName");	//终端登录名
		  
		logger.debug("核销请求数据:\nsn="+sn+"\r\ntime="+time+"\r\nv1="+verify1+"\r\nv2="+verify2+"\r\nclientId="+clientId+"\r\nclientType="+clientType);
		/**
		 * 检查请求参数是否为空
		 */
		if(sn== null || time==null || verify1==null || verify2==null || clientId==null || clientType==null){
			writeToUser(request, response, false, "您提交的数据不完整,请联系管理员", "");
			return false;
		}
		
		/**
		 * 如果不是比特堡
		 */
		if("bitebao".equals(clientId)){
			clientId = "1";
		}
		
		//验证客户端
		this.terminal = terminalService.get(Long.parseLong(clientId));
		if(this.terminal == null){
			writeToUser(request, response, false, "该终端不存在,请先设置好设置配置再行核销", "");
			return false;
		}else{
			if(!BaseEntity.STATUS_NORMAL.equals(terminal.getStatus())){
				writeToUser(request, response, false, "该终端已被锁定,请解除锁定后再使用!", "");
				return false;
			}
		}	
		
		
		String key=Constants.MD5ENCODER_VERIFY_KEY;
		
		String vstr1 =   getMD5EncodeString((time.trim()+key)).replaceAll(" ", "");
		logger.debug("java v1:"+vstr1);
		//验证1
		if(!vstr1.equals(verify1.replaceAll(" ", "+"))){
			writeToUser(request, response, false, "您提交的数据是非法端核销数据请求,请不要尝试破坏和攻击本系统,否则您将受到相关法律的裁,谢谢合作!", "");
			return false;
		} 
		
		//验证2
		String vsn = sn.replaceAll("-", "");
		String vstr2 = getMD5EncodeString((vsn.trim()+key)).replaceAll(" ", "");
		logger.debug("java v2:"+vstr2);
		if(!vstr2.equals(verify2.replaceAll(" ", "+"))){
			writeToUser(request, response, false, "您提交的数据是非法端核销数据请求,请不要尝试破坏和攻击本系统,否则您将受到相关法律的裁,谢谢合作!", "");
			return false;
		} 
		
		return true;
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2014-3-6  上午11:03:29
	 * @function <p> 查询会员 余额和积分  </p>
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value="queryRecharge")
	public String queryRechargMoney(HttpServletRequest request, HttpServletResponse response, Model model){
		if(verifyParameters(request, response, model)){
			String number = request.getParameter("number");		//会员卡号
			User user = terminal.getUser();
			WechatMember member = wechatMemberService.getByUserIdAndNumber(user.getId(), number);
			
			if(member !=null ){
				String xml = wrapMoneyInfoXML(member,0,true,"","查询余额成功.");
				responseXML(request, response, xml);
			}else{
				String xml = wrapMoneyInfoXML(member,0,false,"无法识别的会员二维码,请确认是否已成为我们的会员!","");
				responseXML(request, response, xml);
			}
		}
		
		
		return null;
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2014-3-6  上午10:47:18
	 * @function <p> 充值 信息XML  </p>
	 * @param member
	 * @return
	 */
	private String wrapMoneyInfoXML(WechatMember member,int addscore,boolean success,String errorInfo,String tip){
		
		
		StringBuffer xml = new StringBuffer();
		xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
		xml.append("<response>");
		xml.append("<success>").append(success).append("</success>");
		
		if(member!=null){
			Integer leftMoney = member.getMoney();
			leftMoney = (leftMoney == null) ? 0:leftMoney;
			double qmoney = leftMoney /100.00d;
			DecimalFormat df = new DecimalFormat("0.00");
			String dfMoney = df.format(qmoney);
			
			if(member.getName() != null){
				xml.append("<name>").append(member.getName()).append("</name>");			//奖品名称
			}
			
			if(member.getNickname() != null){
				xml.append("<nickName>").append(member.getNickname()).append("</nickName>");			//奖品名称
			}
			
			if(member.getCreateTime() != null){
				xml.append("<createTime>").append(member.getCreateTime()).append("</createTime>");			//创建时间
			}

			if(member.getActiveScore() != null){
				xml.append("<activeScore>").append(member.getActiveScore()).append("</activeScore>");			//当前积分时间
			}
			
			if(member.getConsumeScore() != null){
				xml.append("<consumeScore>").append(member.getConsumeScore()).append("</consumeScore>");			//当前积分时间
			}
			
			if(member.getCreditScore() != null){
				xml.append("<creditScore>").append(member.getCreditScore()).append("</creditScore>");			//当前积分时间
			}
			
			if(member.getUnusable() != null){
				xml.append("<unusable>").append(member.getUnusable()).append("</unusable>");			//当前积分时间
			}
			
			xml.append("<addscore>").append(addscore).append("</addscore>");			//本次增加
			
			if(member.getSex() != null){
				xml.append("<sex>").append(member.getSex()).append("</sex>");			//奖品名称
			}
			
			
			if(member.getNumber() != null){
				xml.append("<number>").append(member.getNumber()).append("</number>");			//奖品名称
			}
			
			
			if(member.getId() != null){
				xml.append("<id>").append(member.getId()).append("</id>");			//奖品名称
			}
			
			if(dfMoney != null){
				xml.append("<money>").append(dfMoney).append("</money>");			//奖品名称
			}
			
			if(member.getHeadimgurl() != null){
				xml.append("<headimgurl>").append(member.getHeadimgurl()).append("</headimgurl>");			//奖品名称
			}
			
		}
		
		
		xml.append("<errorInfo>").append(errorInfo).append("</errorInfo>");
		xml.append("<tip>").append(tip).append("</tip>");
		xml.append("</response>");
		logger.debug(xml.toString());
		
		return xml.toString();
		
	}
	
	
	
	@RequestMapping(value="payforScore")
	public String payForAddingScoreMoney(HttpServletRequest request, HttpServletResponse response, Model model){
		if(verifyParameters(request, response, model)){
			String number = request.getParameter("number");		//会员卡号
			String uid = request.getParameter("uid");			//
			String money = request.getParameter("money");		//充值金客
			String type  = request.getParameter("type");		//充值金额
			String pwd   = request.getParameter("pwd");
			
			User user = terminal.getUser();
			
			
			
			WechatMember member = wechatMemberService.getByUserIdAndNumber(user.getId(), number);
			
			UserDefine userDefine = WechatUtils.getUserDefineByUserId(user.getId());
			
			Integer moneyForScore = userDefine.getMoneyToScore();
			Integer cmoney = Integer.parseInt(money);	//消费的金额   分
			if(moneyForScore > 0 && cmoney >moneyForScore){
				int addScore = Integer.parseInt(money) /moneyForScore;
				int mScore = member.getActiveScore();
//				member.setScore(mScore+addScore);
//				
//				wechatMemberService.save(member);
				String remarks = "微会员消费"+Double.parseDouble(money)/100 +"元送"+((double)addScore/1000) +"个活动积分.";
				ScoreUtils.addScore(member, addScore,"0",remarks);		//添加积分记录
				
				String xml = wrapMoneyInfoXML(member,addScore, true, "", remarks);
				responseXML(request, response, xml);
				
				return null;
			}else{
				
				String remarks = "";
				if(moneyForScore == null || moneyForScore == 0 ){
					remarks = "暂未找到消费送积分的活动，谢谢!";
				}
				
				if(cmoney < moneyForScore){
					remarks = "对不起,您至少消费"+moneyForScore/100+"元才能获得1个积分，谢谢!";
				}
				String xml = wrapMoneyInfoXML(member,0, false, remarks, "");
				responseXML(request, response, xml);
				
				return null;
			}
			 
			
		}
		
		
		return null;
	}
	
	
	
	
	@RequestMapping(value="pay")
	public String payMoney(HttpServletRequest request, HttpServletResponse response, Model model){
		
		if(verifyParameters(request, response, model)){
			String number = request.getParameter("number");		//会员卡号
			String uid = request.getParameter("uid");			//
			String money = request.getParameter("money");		//充值金客
			String type  = request.getParameter("type");		//充值金额
			String pwd   = request.getParameter("pwd");
			
			User user = terminal.getUser();
			
			WechatMember member = wechatMemberService.getByUserIdAndNumber(user.getId(), number);
			int addscore = 0;
			
			//验证密码
			if(StringUtils.isNotEmpty(member.getPayPassword())){
				if(!EncryptUtils.validatePassword(pwd, member.getPayPassword())){
					String errorInfo ="支付密码错误,支付失败!";
					String xml = wrapMoneyInfoXML(member,addscore, false, errorInfo, "");
					responseXML(request, response, xml);
					return null;
				}
			}else{
				String errorInfo ="您还未设置支付密码,请先设置您的支付密码后再进行支付,谢谢!";
				String xml = wrapMoneyInfoXML(member,addscore, false, errorInfo, "");
				responseXML(request, response, xml);
				return null;
			}
			
			
			Integer leftMoney = member.getMoney();
			Integer payMoney = Integer.parseInt(money);
			Integer lastMoney = leftMoney - payMoney;
			if(payMoney > leftMoney){
				String errorInfo ="余额不足,支付失败!";
				String xml = wrapMoneyInfoXML(member,addscore, false, errorInfo, "");
				responseXML(request, response, xml);
				return null;
			}else{
				// 更新 member
				member.setMoney(lastMoney);
				wechatMemberService.save(member);
				
				//更新 recharge
				Recharge recharge = rechargeService.getRechargeByUserIdAndNumber(this.terminal.getUser().getId(), number);
				recharge.setMoney(lastMoney);
				rechargeService.save(recharge);
				
				
				
				double tempmoney = Double.parseDouble(money)/100;
				DecimalFormat df=new DecimalFormat("#.00");
				String remarkMoney = df.format(tempmoney);
				
				//添加消费记录
				//添加充值日志  流水
				RechargeLog  rechargeLog = new RechargeLog();
				rechargeLog.setMember(member);
				rechargeLog.setUser(user);
				rechargeLog.setName(member.getName());
				rechargeLog.setMoney(-payMoney);
				rechargeLog.setType(RechargeLog.TYPE_CONSUME);
				rechargeLog.setRecharge(recharge);
				rechargeLog.setRemarks("消费"+remarkMoney+"元.");
				String serialNo = wechatDaoHelper.generateRechargeSerialNumber(user.getId());
				rechargeLog.setSerialNo(serialNo);
				rechargeLog.setNumber(member.getNumber());
				rechargeLogService.save(rechargeLog);
				
				
				String xml = wrapMoneyInfoXML(member,addscore, true, "", "成功支付【"+remarkMoney+"】元.");
				responseXML(request, response, xml);
				return null;
				
			}
			
		}
		
		
		return null;
		
	}
	
	
	@RequestMapping(value="modifypwd")
	public String modifyPayPassword(HttpServletRequest request, HttpServletResponse response, Model model){
		
		if(verifyParameters(request, response, model)){
			String number = request.getParameter("number");		//会员卡号
			String uid = request.getParameter("uid");			//
			String money = request.getParameter("money");		//充值金客
			String type  = request.getParameter("type");		//充值金额
			String pwd   = request.getParameter("pwd");
			User user = terminal.getUser();
			WechatMember member = wechatMemberService.getByUserIdAndNumber(user.getId(), number);
			
			//修改密码
			
			
			String payPassword = EncryptUtils.MD5EncodeString(pwd);
			member.setPayPassword(payPassword);
			
			wechatMemberService.save(member);
			
			String successInfo ="修改支付密码成功,谢谢!";
			String xml = wrapMoneyInfoXML(member,0, true, "", successInfo);
			responseXML(request, response, xml);
			return null;
			
		}
		
		
		return null;
		
	}
	
	
	
	
	
	/**
	 * @author Jakemanse
	 * @time 2014-3-4  上午11:05:52
	 * @function <p>会员PC端充值  </p>
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value="recharge")
	public String rechargMoney(HttpServletRequest request, HttpServletResponse response, Model model){
		
		 if(verifyParameters(request, response, model)){
			//检查合法性
				//验证通过
				
				String number = request.getParameter("number");		//会员卡号
				String uid = request.getParameter("uid");			//
				String money = request.getParameter("money");		//充值金客
				String type  = request.getParameter("type");		//充值金额
				
				User user = terminal.getUser();
				WechatMember member = wechatMemberService.getByUserIdAndNumber(user.getId(), number);
				int addscore = 0;
				if(member !=null ){
					Integer leftMoney = member.getMoney();				//当前余额
					leftMoney = (leftMoney==null)?0:leftMoney;		
					
					Integer cmoney = Integer.parseInt(money);			//充值余额
					Integer tmoney = leftMoney+cmoney;					//充值后总金额
					
					
					//查找会员
					Recharge recharge = rechargeService.getRechargeByUserIdAndNumber(this.terminal.getUser().getId(), number);	
					//存在则更新
					if(recharge != null){
						recharge.setMoney(tmoney);
						recharge.setName(member.getName());
						rechargeService.save(recharge);
						member.setMoney(tmoney);
						wechatMemberService.save(member);
						
					}else{
						//不存在则添加
						recharge = new Recharge();
						recharge.setMember(member);
						recharge.setName(member.getName());
						recharge.setUser(user);
						recharge.setMoney(tmoney);
						recharge.setType(type);
						recharge.setNumber(member.getNumber());
						rechargeService.save(recharge);
						
						member.setMoney(tmoney);
						wechatMemberService.save(member);
					}
					
					//添加充值日志  流水
					RechargeLog  rechargeLog = new RechargeLog();
					rechargeLog.setMember(member);
					rechargeLog.setUser(user);
					rechargeLog.setName(member.getName());
					rechargeLog.setMoney(cmoney);
					rechargeLog.setRecharge(recharge);
					rechargeLog.setType(RechargeLog.TYPE_RECHARGE);
					rechargeLog.setRemarks("充值"+cmoney/100+"元.");
					String serialNo = wechatDaoHelper.generateRechargeSerialNumber(user.getId());
					rechargeLog.setNumber(member.getNumber());
					rechargeLog.setSerialNo(serialNo);
					rechargeLogService.save(rechargeLog);
					
					
					String xml = wrapMoneyInfoXML(member,addscore, true, "", "充值成功.");
					responseXML(request, response, xml);
					return null;
				}else{
					writeToUser(request, response, false, "无法识的会员卡二维码", "");
					return null;
				}
				
		 }
		
		 return null;
		
	}
	
	
	
	
	
	public String getMD5EncodeString(String str){
		try {
			MessageDigest md5=MessageDigest.getInstance("MD5"); 
			BASE64Encoder base64en = new BASE64Encoder(); 
			String newstr=base64en.encode(md5.digest(str.getBytes("UTF-8"))); 
			return newstr;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
